﻿/********************************************************************************
    Copyright (C) Binod Nepal, Planet Earth Solutions Pvt. Ltd., Kathmandu.
	Released under the terms of the GNU General Public License, GPL, 
	as published by the Free Software Foundation, either version 3 
	of the License, or (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Threading;
using System.Data;

namespace Pes.Messaging.ApplicationLayer
{
    public static class Emails
    {

        public class Processor
        {
            static bool invalid = false;

            public static void Send(string senderName, string recipients, string subject, string body, string host, int port, bool enableSsl, string userName, string password, string id)
            {
                string[] addresses = recipients.Split(',');
                foreach (string address in addresses)
                {
                    if (!IsValidEmail(address))
                    {
                        return;
                    }
                }

                addresses = addresses.Distinct().ToArray();
                recipients = string.Join(",", addresses);

                ThreadPool.QueueUserWorkItem(callback =>
                {
                    MailAddress sender = new MailAddress(userName, senderName);

                    using (MailMessage mail = new MailMessage(userName, recipients))
                    {
                        mail.From = sender;
                        using (SmtpClient smtp = new SmtpClient(host, port))
                        {
                            smtp.EnableSsl = enableSsl;
                            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
                            smtp.UseDefaultCredentials = false;
                            smtp.Credentials = new NetworkCredential(userName, password);
                            try
                            {
                                mail.Subject = subject;
                                mail.Body = body;
                                mail.IsBodyHtml = true;
                                mail.SubjectEncoding = System.Text.Encoding.UTF8;
                                smtp.Send(mail);
                                Pes.Messaging.DatabaseLayer.Emails.FlagSent(id);
                                LogProvider.log.DebugFormat("Asynchronous Message: EmailId {0} was sent successfully.", id);
                                Console.WriteLine();
                            }
                            catch (SmtpException ex)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                LogProvider.log.Error(ex.Message);
                                System.Diagnostics.EventLog.WriteEntry("PES Messaging Services", ex.Message);
                            }
                        }
                    }
                });
            }

            public static bool IsValidEmail(string strIn)
            {
                invalid = false;

                if (String.IsNullOrWhiteSpace(strIn))
                {
                    return false;
                }

                // Use IdnMapping class to convert Unicode domain names.
                strIn = Regex.Replace(strIn, @"(@)(.+)$", DomainMapper);
                if (invalid)
                {
                    return false;
                }

                // Return true if strIn is in valid e-mail format.
                return Regex.IsMatch(strIn,
                       @"^(?("")(""[^""]+?""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                       @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$",
                       RegexOptions.IgnoreCase);
            }

            private static string DomainMapper(Match match)
            {
                // IdnMapping class with default property values.
                IdnMapping idn = new IdnMapping();

                string domainName = match.Groups[2].Value;
                try
                {
                    domainName = idn.GetAscii(domainName);
                }
                catch (ArgumentException)
                {
                    invalid = true;
                }
                return match.Groups[1].Value + domainName;
            }
        }
    }
}
